#ifndef __THREAD_H__
#define __THREAD_H__

#include <glib.h>
#include <ucontext.h>

/* identifiant de thread
 * NB: pourra être un entier au lieu d'un pointeur si ca vous arrange,
 *     mais attention aux inconvénient des tableaux de threads
 *     (consommation mémoire, cout d'allocation, ...).
 *
 typedef void* thread_t;
 */

/**
 * Struct that defines a thread
 *
 **/
struct thread_t {
  int pid;
  ucontext_t context;
  Glist* threads_list; // GList defining the threads FIFO

};

/**
 * Function that returns the current running thread
 * @return a pointer to the current running thread or NULL
 **/

thread_t thread_self(void);


/**
 * Function that adds a thread to the threads FIFO list, links the desired
 * function to that thread, runs that thread
 * @return 0 if success, -1 if fail
 * @param 
 **/

int thread_create(void *(*func)(void *), void *funcarg);

/* passer la main à un autre thread.
 */
extern int thread_yield(void);

/* attendre la fin d'exécution d'un thread.
 * la valeur renvoyée par le thread est placée dans *retval.
 * si retval est NULL, la valeur de retour est ignorée.
 */
extern int thread_join(thread_t thread, void **retval);

/* terminer le thread courant en renvoyant la valeur de retour retval.
 * cette fonction ne retourne jamais.
 *
 * L'attribut noreturn aide le compilateur à optimiser le code de
 * l'application (élimination de code mort). Attention à ne pas mettre
 * cet attribut dans votre interface tant que votre thread_exit()
 * n'est pas correctement implémenté (il ne doit jamais retourner).
 */
extern void thread_exit(void *retval) __attribute__ ((__noreturn__));

#endif /* __THREAD_H__ */
